“Baby Mental Life: Study 2” was conducted on MTurk on 2018-08-04.

Our planned sample was 300 participants, and we anticipated that roughly 80% of recruited participants would pass all of our attention checks, so we initially recruited 378 participants (on the idea that ~80% of 378 ~ 300 participants; note that for administrative purposes we need to recuit participants in batches that were divisible by 9). After filtering out participants who failed at least one of our attention checks, we ended up retaining fewer than 300 participants, so we recruited an additional 16 participants for a total of 394 people recruited. At each stage, we recruited women and men through separate studies, in hopes of acquiring a roughly equal split between genders.

In the end, we ended up with a sample of 304 participants who passed our attention checks, 237 of whom came from unique GPS coordinates.

For this first pass, these data exclude participants where there is another participant with an identical set of GPS coordinates as recorded by Qualtrics.

Each participant assessed children’s mental capacities at 13 target ages between the ages of 0 and 5 years. For each target, they rated 20 mental capacities on a scale from 0 (not at all capable) to 100 (completely capable).

For more details about the study, see our preregistration here.

Here we run some individual-level regressions on these data.

# load required libraries
library(tidyverse)
── Attaching packages ─────────────────────────────────────── tidyverse 1.2.1 ──
✔ ggplot2 3.0.0     ✔ purrr   0.2.5
✔ tibble  1.4.2     ✔ dplyr   0.7.6
✔ tidyr   0.8.1     ✔ stringr 1.3.1
✔ readr   1.1.1     ✔ forcats 0.3.0
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
library(langcog) # source: https://github.com/langcog/langcog-package

Attaching package: ‘langcog’

The following object is masked from ‘package:base’:

    scale
library(psych)

Attaching package: ‘psych’

The following objects are masked from ‘package:ggplot2’:

    %+%, alpha
library(lme4)
Loading required package: Matrix

Attaching package: ‘Matrix’

The following object is masked from ‘package:tidyr’:

    expand
library(kableExtra)
# set theme for ggplots
theme_set(theme_bw())
# run source code (extra home-made functions)
source("./scripts/max_factors_efa.R")
source("./scripts/plot_fun.R")
source("./scripts/reten_fun.R")
source("./scripts/table_fun.R")
source("./scripts/data_prep.R")
NAs introduced by coercionattributes are not identical across measure variables;
they will be droppedJoining, by = "question_qualtrics"

Treating factors as categories

Preliminaries

First, I’ll do the factor analysis, and get a list of the top 5 items by factor:

# load in S1 efa in case we need it
efa_S1 <- readRDS("../study 1/s1_efa.rds")
d_all_S1 <- read.csv("../study 1/s1_data.csv")
demo_S1 <- read.csv("../study 1/s1_demo.csv")
# conduct S2 efa
efa_S2 <- fa(d_all, nfactors = 4, rotate = "oblimin", fm = "minres",
             scores = "tenBerge", impute = "median")
Loading required namespace: GPArotation
table_fun(efa_S2, num_items = 5, pos_abs = "abs")
capacity loading
Factor 1
feeling_distressed 0.82
feeling_overwhelmed 0.82
feeling_frustrated 0.78
feeling_helpless 0.76
feeling_lonely 0.60
Factor 2
having_self_control 0.96
controlling_their_emotions 0.93
telling_right_from_wrong 0.93
planning 0.89
reasoning_about_things 0.89
Factor 3
getting_hungry 0.83
feeling_pain 0.79
feeling_tired 0.67
hearing_sounds 0.58
feeling_physically_uncomfortable 0.49
Factor 4
feeling_happy 0.82
finding_something_funny 0.81
feeling_excited 0.79
loving_somebody 0.64
learning_from_other_people 0.51

Now I’ll use this to define categories of mental capacities:

# get items by factor
factors_S2 <- efa_S2$loadings[] %>%
  data.frame() %>%
  rownames_to_column("capacity") %>%
  gather(factor, loading, -capacity) %>%
  group_by(capacity) %>%
  top_n(1, loading) %>%
  ungroup() %>%
  select(-loading) %>%
  mutate(factor_names = recode_factor(factor,
                                      "MR1" = "Negative emotions",
                                      "MR2" = "Cognition & control",
                                      "MR3" = "Bodily sensations",
                                      "MR4" = "Positive/social emotions"),
         factor = factor(factor))
# make new dataframe
d_cat <- d_all %>%
  rownames_to_column("subid_target") %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(capacity, response, -c(subid, starts_with("target"))) %>%
  left_join(factors_S2) %>%
  left_join(d_demo %>%
              select(ResponseId, Parent) %>%
              rename(subid = ResponseId, parent = Parent) %>%
              mutate(subid = as.character(subid)))
Joining, by = "capacity"
Joining, by = "subid"

Check reliability (Cronbach’s alpha):

d_cat %>% 
  filter(factor == "MR1") %>% 
  mutate(subid_target = paste(subid, target, sep = "_")) %>%
  select(subid_target, capacity, response) %>%
  spread(capacity, response) %>%
  column_to_rownames("subid_target") %>%
  cor() %>%
  alpha(title = "MR1: Negative emotions")

Reliability analysis  MR1: Negative emotions  
Call: alpha(x = ., title = "MR1: Negative emotions")

 

 Reliability if an item is dropped:

 Item statistics 
d_cat %>% 
  filter(factor == "MR2") %>% 
  mutate(subid_target = paste(subid, target, sep = "_")) %>%
  select(subid_target, capacity, response) %>%
  spread(capacity, response) %>%
  column_to_rownames("subid_target") %>%
  cor() %>%
  alpha(title = "MR2: Cognition & control")

Reliability analysis  MR2: Cognition & control  
Call: alpha(x = ., title = "MR2: Cognition & control")

 

 Reliability if an item is dropped:

 Item statistics 
d_cat %>% 
  filter(factor == "MR3") %>% 
  mutate(subid_target = paste(subid, target, sep = "_")) %>%
  select(subid_target, capacity, response) %>%
  spread(capacity, response) %>%
  column_to_rownames("subid_target") %>%
  cor() %>%
  alpha(title = "MR3: Bodily sensations")

Reliability analysis  MR3: Bodily sensations  
Call: alpha(x = ., title = "MR3: Bodily sensations")

 

 Reliability if an item is dropped:

 Item statistics 
d_cat %>% 
  filter(factor == "MR4") %>% 
  mutate(subid_target = paste(subid, target, sep = "_")) %>%
  select(subid_target, capacity, response) %>%
  spread(capacity, response) %>%
  column_to_rownames("subid_target") %>%
  cor() %>%
  alpha(title = "MR4: Social abilities & positive emotions")

Reliability analysis  MR4: Social abilities & positive emotions  
Call: alpha(x = ., title = "MR4: Social abilities & positive emotions")

 

 Reliability if an item is dropped:

 Item statistics 

And get an average “score” for each of these factors for each participant:

d_cat_scored <- d_cat %>%
  group_by(subid, parent, 
           target, target_num, target_ord, 
           factor, factor_names) %>%
  summarise(score = mean(response, na.rm = T)) %>%
  ungroup()

Plots

# bootstrapped means and 95% CIs
d_cat_scored_boot <- d_cat_scored %>%
  group_by(target, target_num, target_ord, factor, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup()

|==============                                        | 27% ~5 s remaining     
|===============                                       | 29% ~5 s remaining     
|================                                      | 31% ~5 s remaining     
|=================                                     | 33% ~5 s remaining     
|==================                                    | 35% ~4 s remaining     
|===================                                   | 37% ~4 s remaining     
|====================                                  | 38% ~4 s remaining     
|=====================                                 | 40% ~4 s remaining     
|======================                                | 42% ~4 s remaining     
|=======================                               | 44% ~3 s remaining     
|========================                              | 46% ~3 s remaining     
|===========================                           | 50% ~3 s remaining     
|============================                          | 52% ~3 s remaining     
|=============================                         | 54% ~3 s remaining     
|==============================                        | 56% ~3 s remaining     
|================================                      | 60% ~2 s remaining     
|==================================                    | 63% ~2 s remaining     
|===================================                   | 65% ~2 s remaining     
|====================================                  | 67% ~2 s remaining     
|======================================                | 71% ~1 s remaining     
|=======================================               | 73% ~1 s remaining     
|========================================              | 75% ~1 s remaining     
|=========================================             | 77% ~1 s remaining     
|===========================================           | 81% ~1 s remaining     
|============================================          | 83% ~1 s remaining     
|=============================================         | 85% ~1 s remaining     
|===============================================       | 88% ~1 s remaining     
|=================================================     | 92% ~0 s remaining     
|===================================================   | 96% ~0 s remaining     
|====================================================  | 98% ~0 s remaining     
|======================================================|100% ~0 s remaining     
ggplot(d_cat_scored,
       aes(x = target_num, y = score, color = factor_names)) +
  facet_grid(~ factor_names) +
  geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_scored_boot, color = "black",
            aes(y = mean, group = factor_names)) +
  geom_pointrange(data = d_cat_scored_boot, color = "black", fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Set2", guide = "none") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, untransformed",
       x = "target age (months)")

Regression

# contrasts(d_cat_scored$factor) <- cbind(cog_gm = c(-1, 1, 0, 0),
#                                         bod_gm = c(-1, 0, 1, 0),
#                                         pos_gm = c(-1, 0, 0, 1))
# 
# r1 <- lmer(score ~ factor * poly(target_num, 3) + 
#              (1 + factor + poly(target_num, 1) | subid),
#            d_cat_scored %>%
#              mutate(target_num = scale(target_num, center = F)))
#            # control = lmerControl(optCtrl = list(maxfun = 1e5))) # source: https://stat.ethz.ch/pipermail/r-sig-mixed-models/2014q2/022084.html
# 
# summary(r1)
# ranef(r1) %>%
#   data.frame() %>%
#   ggplot(aes(x = condval)) +
#   facet_grid(~term, scales = "free") +
#   geom_histogram() +
#   geom_vline(xintercept = 0, lty = 2, color = "blue")

Individual regressions

subids <- levels(factor(d_cat$subid)) %>% as.numeric()
# reminder of contrasts
contrasts(d_cat_scored$factor)
    cog_gm bod_gm pos_gm
MR1     -1     -1     -1
MR2      1      0      0
MR3      0      1      0
MR4      0      0      1
reg_fun <- function(this_subid){
  r <- lm(score ~ factor * poly(target_num, 3),
          d_cat_scored %>% filter(subid == this_subid))
  
  coeffs <- summary(r)$coefficients %>%
    data.frame() %>%
    rownames_to_column("param") %>%
    mutate(subid = this_subid)
  
  return(coeffs)
}

indiv_coeffs <- data.frame(param = character(),
                           Estimate = numeric(),
                           Std..Error = numeric(),
                           t.value = numeric(),
                           Pr...t.. = numeric(),
                           subid = numeric())
for(i in 1:length(subids)){
  current_coeffs <- reg_fun(subids[i])
  indiv_coeffs <- indiv_coeffs %>%
    full_join(current_coeffs)
}

indiv_coeffs <- indiv_coeffs %>%
  rename(b = Estimate,
         b_se = Std..Error,
         t = t.value,
         t_p = Pr...t..)
indiv_coeffs %>%
  mutate(signif = case_when(t_p < 0.00001 ~ "p < 0.00001", 
                            t_p < 0.0001 ~ "p < 0.0001",
                            t_p < 0.001 ~ "p < 0.001",
                            t_p < 0.01 ~ "p < 0.01",
                            t_p < 0.05 ~ "p < 0.05",
                            t_p >= 0.05 ~ "n.s."),
         signif = factor(signif,
                         levels = c("n.s.", "p < 0.05", "p < 0.01", "p < 0.001",
                                    "p < 0.0001", "p < 0.00001")),
         param = recode_factor(param,
                               "(Intercept)" = "overall at birth",
                               "poly(target_num, 3)1" = "overall linear",
                               "poly(target_num, 3)2" = "overall quadratic",
                               "poly(target_num, 3)3" = "overall cubic",
                               "factorbod_gm" = "bodily at birth vs. GM",
                               "factorbod_gm:poly(target_num, 3)1" = 
                                 "bodily linear vs. GM",
                               "factorbod_gm:poly(target_num, 3)2" = 
                                 "bodily quadratic vs. GM",
                               "factorbod_gm:poly(target_num, 3)3" = 
                                 "bodily cubic vs. GM",
                               "factorcog_gm" = "cognitive at birth vs. GM",
                               "factorcog_gm:poly(target_num, 3)1" = 
                                 "cognitive linear vs. GM",
                               "factorcog_gm:poly(target_num, 3)2" = 
                                 "cognitive quadratic vs. GM",
                               "factorcog_gm:poly(target_num, 3)3" = 
                                 "cognitive cubic vs. GM",
                               "factorpos_gm" = "positive at birth vs. GM",
                               "factorpos_gm:poly(target_num, 3)1" = 
                                 "positive linear vs. GM",
                               "factorpos_gm:poly(target_num, 3)2" = 
                                 "positive quadratic vs. GM",
                               "factorpos_gm:poly(target_num, 3)3" = 
                                 "positive cubic vs. GM"),
         factor = case_when(grepl("overall", param) ~ "overall",
                            # grepl("neg", param) ~ "negative emotions",
                            grepl("bod", param) ~ "bodily sensations",
                            grepl("cog", param) ~ "cognition & control",
                            grepl("pos", param) ~ "positive/social emotions"),
         factor = factor(factor,
                         levels = c("overall",
                                    #"negative emotions", 
                                    "cognition & control",
                                    "bodily sensations",  
                                    "positive/social emotions"))) %>%
  ggplot(aes(x = b, fill = factor, alpha = signif)) +
  facet_wrap(~ param, scales = "free") +
  geom_histogram(fill = "black", alpha = 1) +
  geom_histogram() +
  # scale_fill_brewer(palette = "Set2", na.value = "gray")
  scale_fill_manual(values = c("#a6d854", "#fc8d62", "#8da0cb", "#e78ac3"))

indiv_coeffs %>%
  select(subid, param, b) %>%
  spread(param, b) %>%
  arrange(desc(`factorbod_gm:poly(target_num, 3)1`),
          desc(`factorbod_gm:poly(target_num, 3)2`),
          desc(`factorbod_gm:poly(target_num, 3)3`)) %>%
  mutate(order = 1:length(subids))
d_cat_scored %>%
  filter(factor == "MR3") %>% # MR3 = bodily sensations
  full_join(d_cat_scored %>%
              filter(target_num == 0, factor == "MR3") %>%
              distinct(subid, score) %>%
              arrange(score) %>%
              mutate(order = 1:length(subids),
                     subid = as.character(subid)) %>%
              distinct(subid, order)) %>%
  # full_join(indiv_coeffs %>%
  #             select(subid, param, b) %>%
  #             spread(param, b) %>%
  #             arrange(`factorbod_gm`) %>%
  #             # arrange(desc(`factorbod_gm:poly(target_num, 3)1`)) %>%
  #             mutate(order = 1:length(subids),
  #                    subid = as.character(subid)) %>%
  #             distinct(subid, order)) %>%
  ggplot(aes(x = target_num, y = score)) + 
  facet_wrap(~ reorder(subid, order)) +
  geom_line(color = "#8da0cb", size = 1) +
  labs(title = "Bodily sensations",
       # subtitle = "Ordered by coefficient of bodily sensations (vs. GM)")
       subtitle = "Ordered by perceived bodily sensations at birth")
Joining, by = "subid"

d_cat_scored %>%
  filter(factor == "MR2") %>% # MR2 = cognition & control
  full_join(d_cat_scored %>%
              filter(target_num == 0, factor == "MR2") %>%
              distinct(subid, score) %>%
              arrange(score) %>%
              mutate(order = 1:length(subids),
                     subid = as.character(subid)) %>%
              distinct(subid, order)) %>%
  # full_join(indiv_coeffs %>%
  #             select(subid, param, b) %>%
  #             spread(param, b) %>%
  #             arrange(`factorcog_gm`) %>%
  #             # arrange(desc(`factorcog_gm:poly(target_num, 3)1`)) %>%
  #             mutate(order = 1:length(subids),
  #                    subid = as.character(subid)) %>%
  #             distinct(subid, order)) %>%
  ggplot(aes(x = target_num, y = score)) + 
  facet_wrap(~ reorder(subid, order)) +
  geom_line(color = "#fc8d62", size = 1) +
  labs(title = "Cognition & control",
       # subtitle = "Ordered by coefficient of cognition & control (vs. GM)")
       subtitle = "Ordered by perceived cognition & control at birth")
Joining, by = "subid"

d_cat_scored %>%
  filter(factor == "MR4") %>% # MR4 = positive/social emotions
  full_join(d_cat_scored %>%
              filter(target_num == 0, factor == "MR4") %>%
              distinct(subid, score) %>%
              arrange(score) %>%
              mutate(order = 1:length(subids),
                     subid = as.character(subid)) %>%
              distinct(subid, order)) %>%
  # full_join(indiv_coeffs %>%
  #             select(subid, param, b) %>%
  #             spread(param, b) %>%
  #             arrange(`factorpos_gm`) %>%
  #             # arrange(desc(`factorpos_gm:poly(target_num, 3)1`)) %>%
  #             mutate(order = 1:length(subids),
  #                    subid = as.character(subid)) %>%
  #             distinct(subid, order)) %>%
  ggplot(aes(x = target_num, y = score)) + 
  facet_wrap(~ reorder(subid, order)) +
  geom_line(color = "#e78ac3", size = 1) +
  labs(title = "Positive/social emotions",
       # subtitle = "Ordered by coefficient of positive/social emotions (vs. GM)")
       subtitle = "Ordered by perceived positive/social emotions at birth")
Joining, by = "subid"

d_cat_scored %>%
  filter(factor == "MR1") %>% # MR1 = negative emotions
  full_join(d_cat_scored %>%
              filter(target_num == 0, factor == "MR1") %>%
              distinct(subid, score) %>%
              arrange(score) %>%
              mutate(order = 1:length(subids),
                     subid = as.character(subid)) %>%
              distinct(subid, order)) %>%
  # full_join(indiv_coeffs %>%
  #             select(subid, param, b) %>%
  #             spread(param, b) %>%
  #             arrange(`factorneg_gm`) %>%
  #             # arrange(desc(`factorneg_gm:poly(target_num, 3)1`)) %>%
  #             mutate(order = 1:length(subids),
  #                    subid = as.character(subid)) %>%
  #             distinct(subid, order)) %>%
  ggplot(aes(x = target_num, y = score)) + 
  facet_wrap(~ reorder(subid, order)) +
  geom_line(color = "#66c2a5", size = 1) +
  labs(title = "Negative emotions",
       # subtitle = "Ordered by coefficient of negative emotions (vs. GM)")
       subtitle = "Ordered by perceived negative emotions at birth")
Joining, by = "subid"

LS0tCnRpdGxlOiAiQmFieSBNZW50YWwgTGlmZTogU3R1ZHkgMiIKc3VidGl0bGU6ICJJbmRpdmlkdWFsIHJlZ3Jlc3Npb25zIgpkYXRlOiAyMDE4LTEyLTE3Cm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKIkJhYnkgTWVudGFsIExpZmU6IFN0dWR5IDIiIHdhcyBjb25kdWN0ZWQgb24gTVR1cmsgb24gMjAxOC0wOC0wNC4KCk91ciBwbGFubmVkIHNhbXBsZSB3YXMgMzAwIHBhcnRpY2lwYW50cywgYW5kIHdlIGFudGljaXBhdGVkIHRoYXQgcm91Z2hseSA4MCUgb2YgcmVjcnVpdGVkIHBhcnRpY2lwYW50cyB3b3VsZCBwYXNzIGFsbCBvZiBvdXIgYXR0ZW50aW9uIGNoZWNrcywgc28gd2UgaW5pdGlhbGx5IHJlY3J1aXRlZCAzNzggcGFydGljaXBhbnRzIChvbiB0aGUgaWRlYSB0aGF0IH44MCUgb2YgMzc4IH4gMzAwIHBhcnRpY2lwYW50czsgbm90ZSB0aGF0IGZvciBhZG1pbmlzdHJhdGl2ZSBwdXJwb3NlcyB3ZSBuZWVkIHRvIHJlY3VpdCBwYXJ0aWNpcGFudHMgaW4gYmF0Y2hlcyB0aGF0IHdlcmUgZGl2aXNpYmxlIGJ5IDkpLiBBZnRlciBmaWx0ZXJpbmcgb3V0IHBhcnRpY2lwYW50cyB3aG8gZmFpbGVkIGF0IGxlYXN0IG9uZSBvZiBvdXIgYXR0ZW50aW9uIGNoZWNrcywgd2UgZW5kZWQgdXAgcmV0YWluaW5nIGZld2VyIHRoYW4gMzAwIHBhcnRpY2lwYW50cywgc28gd2UgcmVjcnVpdGVkIGFuIGFkZGl0aW9uYWwgMTYgcGFydGljaXBhbnRzIGZvciBhIHRvdGFsIG9mIDM5NCBwZW9wbGUgcmVjcnVpdGVkLiBBdCBlYWNoIHN0YWdlLCB3ZSByZWNydWl0ZWQgd29tZW4gYW5kIG1lbiB0aHJvdWdoIHNlcGFyYXRlIHN0dWRpZXMsIGluIGhvcGVzIG9mIGFjcXVpcmluZyBhIHJvdWdobHkgZXF1YWwgc3BsaXQgYmV0d2VlbiBnZW5kZXJzLgoKSW4gdGhlIGVuZCwgd2UgZW5kZWQgdXAgd2l0aCBhIHNhbXBsZSBvZiAzMDQgcGFydGljaXBhbnRzIHdobyBwYXNzZWQgb3VyIGF0dGVudGlvbiBjaGVja3MsIDIzNyBvZiB3aG9tIGNhbWUgZnJvbSB1bmlxdWUgR1BTIGNvb3JkaW5hdGVzLgoKKipGb3IgdGhpcyBmaXJzdCBwYXNzLCB0aGVzZSBkYXRhIF9leGNsdWRlXyBwYXJ0aWNpcGFudHMgd2hlcmUgdGhlcmUgaXMgYW5vdGhlciBwYXJ0aWNpcGFudCB3aXRoIGFuIGlkZW50aWNhbCBzZXQgb2YgR1BTIGNvb3JkaW5hdGVzIGFzIHJlY29yZGVkIGJ5IFF1YWx0cmljcy4qKgoKRWFjaCBwYXJ0aWNpcGFudCBhc3Nlc3NlZCBjaGlsZHJlbidzIG1lbnRhbCBjYXBhY2l0aWVzIGF0IDEzIHRhcmdldCBhZ2VzIGJldHdlZW4gdGhlIGFnZXMgb2YgMCBhbmQgNSB5ZWFycy4gRm9yIGVhY2ggdGFyZ2V0LCB0aGV5IHJhdGVkIDIwIG1lbnRhbCBjYXBhY2l0aWVzIG9uIGEgc2NhbGUgZnJvbSAwIChub3QgYXQgYWxsIGNhcGFibGUpIHRvIDEwMCAoY29tcGxldGVseSBjYXBhYmxlKS4gCgpGb3IgbW9yZSBkZXRhaWxzIGFib3V0IHRoZSBzdHVkeSwgc2VlIG91ciBwcmVyZWdpc3RyYXRpb24gW2hlcmVdKGh0dHBzOi8vb3NmLmlvL2o3MmRnLykuIAoKKipIZXJlIHdlIHJ1biBzb21lIGluZGl2aWR1YWwtbGV2ZWwgcmVncmVzc2lvbnMgb24gdGhlc2UgZGF0YS4qKgoKYGBge3J9CiMgbG9hZCByZXF1aXJlZCBsaWJyYXJpZXMKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobGFuZ2NvZykgIyBzb3VyY2U6IGh0dHBzOi8vZ2l0aHViLmNvbS9sYW5nY29nL2xhbmdjb2ctcGFja2FnZQpsaWJyYXJ5KHBzeWNoKQpsaWJyYXJ5KGxtZTQpCmxpYnJhcnkoa2FibGVFeHRyYSkKCiMgc2V0IHRoZW1lIGZvciBnZ3Bsb3RzCnRoZW1lX3NldCh0aGVtZV9idygpKQpgYGAKCmBgYHtyfQojIHJ1biBzb3VyY2UgY29kZSAoZXh0cmEgaG9tZS1tYWRlIGZ1bmN0aW9ucykKc291cmNlKCIuL3NjcmlwdHMvbWF4X2ZhY3RvcnNfZWZhLlIiKQpzb3VyY2UoIi4vc2NyaXB0cy9wbG90X2Z1bi5SIikKc291cmNlKCIuL3NjcmlwdHMvcmV0ZW5fZnVuLlIiKQpzb3VyY2UoIi4vc2NyaXB0cy90YWJsZV9mdW4uUiIpCnNvdXJjZSgiLi9zY3JpcHRzL2RhdGFfcHJlcC5SIikKYGBgCgojIFRyZWF0aW5nIGZhY3RvcnMgYXMgY2F0ZWdvcmllcwoKIyMgUHJlbGltaW5hcmllcwoKRmlyc3QsIEknbGwgZG8gdGhlIGZhY3RvciBhbmFseXNpcywgYW5kIGdldCBhIGxpc3Qgb2YgdGhlIHRvcCA1IGl0ZW1zIGJ5IGZhY3RvcjoKCmBgYHtyfQojIGxvYWQgaW4gUzEgZWZhIGluIGNhc2Ugd2UgbmVlZCBpdAplZmFfUzEgPC0gcmVhZFJEUygiLi4vc3R1ZHkgMS9zMV9lZmEucmRzIikKZF9hbGxfUzEgPC0gcmVhZC5jc3YoIi4uL3N0dWR5IDEvczFfZGF0YS5jc3YiKQpkZW1vX1MxIDwtIHJlYWQuY3N2KCIuLi9zdHVkeSAxL3MxX2RlbW8uY3N2IikKYGBgCgpgYGB7cn0KIyBjb25kdWN0IFMyIGVmYQplZmFfUzIgPC0gZmEoZF9hbGwsIG5mYWN0b3JzID0gNCwgcm90YXRlID0gIm9ibGltaW4iLCBmbSA9ICJtaW5yZXMiLAogICAgICAgICAgICAgc2NvcmVzID0gInRlbkJlcmdlIiwgaW1wdXRlID0gIm1lZGlhbiIpCmBgYAoKYGBge3J9CnRhYmxlX2Z1bihlZmFfUzIsIG51bV9pdGVtcyA9IDUsIHBvc19hYnMgPSAiYWJzIikKYGBgCgpOb3cgSSdsbCB1c2UgdGhpcyB0byBkZWZpbmUgY2F0ZWdvcmllcyBvZiBtZW50YWwgY2FwYWNpdGllczoKCmBgYHtyfQojIGdldCBpdGVtcyBieSBmYWN0b3IKZmFjdG9yc19TMiA8LSBlZmFfUzIkbG9hZGluZ3NbXSAlPiUKICBkYXRhLmZyYW1lKCkgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCJjYXBhY2l0eSIpICU+JQogIGdhdGhlcihmYWN0b3IsIGxvYWRpbmcsIC1jYXBhY2l0eSkgJT4lCiAgZ3JvdXBfYnkoY2FwYWNpdHkpICU+JQogIHRvcF9uKDEsIGxvYWRpbmcpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBzZWxlY3QoLWxvYWRpbmcpICU+JQogIG11dGF0ZShmYWN0b3JfbmFtZXMgPSByZWNvZGVfZmFjdG9yKGZhY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVIxIiA9ICJOZWdhdGl2ZSBlbW90aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1SMiIgPSAiQ29nbml0aW9uICYgY29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1SMyIgPSAiQm9kaWx5IHNlbnNhdGlvbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNUjQiID0gIlBvc2l0aXZlL3NvY2lhbCBlbW90aW9ucyIpLAogICAgICAgICBmYWN0b3IgPSBmYWN0b3IoZmFjdG9yKSkKCiMgbWFrZSBuZXcgZGF0YWZyYW1lCmRfY2F0IDwtIGRfYWxsICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigic3ViaWRfdGFyZ2V0IikgJT4lCiAgbXV0YXRlKHN1YmlkID0gZ3N1YigiXy4qJCIsICIiLCBzdWJpZF90YXJnZXQpLAogICAgICAgICB0YXJnZXQgPSBnc3ViKCJeLipfIiwgIiIsIHN1YmlkX3RhcmdldCkpICU+JQogIHNlbGVjdCgtc3ViaWRfdGFyZ2V0KSAlPiUKICBtdXRhdGUodGFyZ2V0X251bSA9IHJlY29kZSh0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAwbW8iID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MFhtbyIgPSA0LzMwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMW1vIiA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAybW8iID0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDRtbyIgPSA0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNm1vIiA9IDYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA5bW8iID0gOSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MTJtbyIgPSAxMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MThtbyIgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MjRtbyIgPSAyNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MzZtbyIgPSAzNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NDhtbyIgPSA0OCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NjBtbyIgPSA2MCksCiAgICAgICAgIHRhcmdldF9vcmQgPSByZWNvZGVfZmFjdG9yKHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAwbW8iID0gIm5ld2Jvcm5zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDBYbW8iID0gIjQtZGF5LW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDFtbyIgPSAiMS1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAybW8iID0gIjItbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNG1vIiA9ICI0LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDZtbyIgPSAiNi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA5bW8iID0gIjktbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxMm1vIiA9ICIxMi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDE4bW8iID0gIjE4LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MjRtbyIgPSAiMi15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MzZtbyIgPSAiMy15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NDhtbyIgPSAiNC15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NjBtbyIgPSAiNS15ZWFyLW9sZHMiKSkgJT4lCiAgZ2F0aGVyKGNhcGFjaXR5LCByZXNwb25zZSwgLWMoc3ViaWQsIHN0YXJ0c193aXRoKCJ0YXJnZXQiKSkpICU+JQogIGxlZnRfam9pbihmYWN0b3JzX1MyKSAlPiUKICBsZWZ0X2pvaW4oZF9kZW1vICU+JQogICAgICAgICAgICAgIHNlbGVjdChSZXNwb25zZUlkLCBQYXJlbnQpICU+JQogICAgICAgICAgICAgIHJlbmFtZShzdWJpZCA9IFJlc3BvbnNlSWQsIHBhcmVudCA9IFBhcmVudCkgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKHN1YmlkID0gYXMuY2hhcmFjdGVyKHN1YmlkKSkpCmBgYAoKQ2hlY2sgcmVsaWFiaWxpdHkgKENyb25iYWNoJ3MgYWxwaGEpOgoKYGBge3J9CmRfY2F0ICU+JSAKICBmaWx0ZXIoZmFjdG9yID09ICJNUjEiKSAlPiUgCiAgbXV0YXRlKHN1YmlkX3RhcmdldCA9IHBhc3RlKHN1YmlkLCB0YXJnZXQsIHNlcCA9ICJfIikpICU+JQogIHNlbGVjdChzdWJpZF90YXJnZXQsIGNhcGFjaXR5LCByZXNwb25zZSkgJT4lCiAgc3ByZWFkKGNhcGFjaXR5LCByZXNwb25zZSkgJT4lCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJzdWJpZF90YXJnZXQiKSAlPiUKICBjb3IoKSAlPiUKICBhbHBoYSh0aXRsZSA9ICJNUjE6IE5lZ2F0aXZlIGVtb3Rpb25zIikKYGBgCgpgYGB7cn0KZF9jYXQgJT4lIAogIGZpbHRlcihmYWN0b3IgPT0gIk1SMiIpICU+JSAKICBtdXRhdGUoc3ViaWRfdGFyZ2V0ID0gcGFzdGUoc3ViaWQsIHRhcmdldCwgc2VwID0gIl8iKSkgJT4lCiAgc2VsZWN0KHN1YmlkX3RhcmdldCwgY2FwYWNpdHksIHJlc3BvbnNlKSAlPiUKICBzcHJlYWQoY2FwYWNpdHksIHJlc3BvbnNlKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoInN1YmlkX3RhcmdldCIpICU+JQogIGNvcigpICU+JQogIGFscGhhKHRpdGxlID0gIk1SMjogQ29nbml0aW9uICYgY29udHJvbCIpCmBgYAoKYGBge3J9CmRfY2F0ICU+JSAKICBmaWx0ZXIoZmFjdG9yID09ICJNUjMiKSAlPiUgCiAgbXV0YXRlKHN1YmlkX3RhcmdldCA9IHBhc3RlKHN1YmlkLCB0YXJnZXQsIHNlcCA9ICJfIikpICU+JQogIHNlbGVjdChzdWJpZF90YXJnZXQsIGNhcGFjaXR5LCByZXNwb25zZSkgJT4lCiAgc3ByZWFkKGNhcGFjaXR5LCByZXNwb25zZSkgJT4lCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJzdWJpZF90YXJnZXQiKSAlPiUKICBjb3IoKSAlPiUKICBhbHBoYSh0aXRsZSA9ICJNUjM6IEJvZGlseSBzZW5zYXRpb25zIikKYGBgCgpgYGB7cn0KZF9jYXQgJT4lIAogIGZpbHRlcihmYWN0b3IgPT0gIk1SNCIpICU+JSAKICBtdXRhdGUoc3ViaWRfdGFyZ2V0ID0gcGFzdGUoc3ViaWQsIHRhcmdldCwgc2VwID0gIl8iKSkgJT4lCiAgc2VsZWN0KHN1YmlkX3RhcmdldCwgY2FwYWNpdHksIHJlc3BvbnNlKSAlPiUKICBzcHJlYWQoY2FwYWNpdHksIHJlc3BvbnNlKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoInN1YmlkX3RhcmdldCIpICU+JQogIGNvcigpICU+JQogIGFscGhhKHRpdGxlID0gIk1SNDogU29jaWFsIGFiaWxpdGllcyAmIHBvc2l0aXZlIGVtb3Rpb25zIikKYGBgCgpBbmQgZ2V0IGFuIGF2ZXJhZ2UgInNjb3JlIiBmb3IgZWFjaCBvZiB0aGVzZSBmYWN0b3JzIGZvciBlYWNoIHBhcnRpY2lwYW50OgoKYGBge3J9CmRfY2F0X3Njb3JlZCA8LSBkX2NhdCAlPiUKICBncm91cF9ieShzdWJpZCwgcGFyZW50LCAKICAgICAgICAgICB0YXJnZXQsIHRhcmdldF9udW0sIHRhcmdldF9vcmQsIAogICAgICAgICAgIGZhY3RvciwgZmFjdG9yX25hbWVzKSAlPiUKICBzdW1tYXJpc2Uoc2NvcmUgPSBtZWFuKHJlc3BvbnNlLCBuYS5ybSA9IFQpKSAlPiUKICB1bmdyb3VwKCkKYGBgCgoKIyMgUGxvdHMKCmBgYHtyfQojIGJvb3RzdHJhcHBlZCBtZWFucyBhbmQgOTUlIENJcwpkX2NhdF9zY29yZWRfYm9vdCA8LSBkX2NhdF9zY29yZWQgJT4lCiAgZ3JvdXBfYnkodGFyZ2V0LCB0YXJnZXRfbnVtLCB0YXJnZXRfb3JkLCBmYWN0b3IsIGZhY3Rvcl9uYW1lcykgJT4lCiAgbXVsdGlfYm9vdF9zdGFuZGFyZCgic2NvcmUiKSAlPiUKICB1bmdyb3VwKCkKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNCwgZmlnLmFzcCA9IDAuNX0KZ2dwbG90KGRfY2F0X3Njb3JlZCwKICAgICAgIGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IGZhY3Rvcl9uYW1lcykpICsKICBmYWNldF9ncmlkKH4gZmFjdG9yX25hbWVzKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjE1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX2NhdF9zY29yZWRfYm9vdCwgY29sb3IgPSAiYmxhY2siLAogICAgICAgICAgICBhZXMoeSA9IG1lYW4sIGdyb3VwID0gZmFjdG9yX25hbWVzKSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9jYXRfc2NvcmVkX2Jvb3QsIGNvbG9yID0gImJsYWNrIiwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSkgKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZmFjdG9yX25hbWVzKSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAieSB+IHBvbHkoeCwgMykiLAogICMgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIsIGd1aWRlID0gIm5vbmUiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpKSArCiAgbGFicyh0aXRsZSA9ICJEZXZlbG9wbWVudGFsIHRyYWplY3RvcmllcyBvZiBjYXRlZ29yeSAnc3VtbWFyeSBzY29yZXMnIiwKICAgICAgIHN1YnRpdGxlID0gIkV4YWN0IGFnZSwgdW50cmFuc2Zvcm1lZCIsCiAgICAgICB4ID0gInRhcmdldCBhZ2UgKG1vbnRocykiKQpgYGAKCgojIyBSZWdyZXNzaW9uCgpgYGB7cn0KIyBjb250cmFzdHMoZF9jYXRfc2NvcmVkJGZhY3RvcikgPC0gY2JpbmQoY29nX2dtID0gYygtMSwgMSwgMCwgMCksCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvZF9nbSA9IGMoLTEsIDAsIDEsIDApLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NfZ20gPSBjKC0xLCAwLCAwLCAxKSkKIyAKIyByMSA8LSBsbWVyKHNjb3JlIH4gZmFjdG9yICogcG9seSh0YXJnZXRfbnVtLCAzKSArIAojICAgICAgICAgICAgICAoMSArIGZhY3RvciArIHBvbHkodGFyZ2V0X251bSwgMSkgfCBzdWJpZCksCiMgICAgICAgICAgICBkX2NhdF9zY29yZWQgJT4lCiMgICAgICAgICAgICAgIG11dGF0ZSh0YXJnZXRfbnVtID0gc2NhbGUodGFyZ2V0X251bSwgY2VudGVyID0gRikpKQojICAgICAgICAgICAgIyBjb250cm9sID0gbG1lckNvbnRyb2wob3B0Q3RybCA9IGxpc3QobWF4ZnVuID0gMWU1KSkpICMgc291cmNlOiBodHRwczovL3N0YXQuZXRoei5jaC9waXBlcm1haWwvci1zaWctbWl4ZWQtbW9kZWxzLzIwMTRxMi8wMjIwODQuaHRtbAojIAojIHN1bW1hcnkocjEpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAwLjI1fQojIHJhbmVmKHIxKSAlPiUKIyAgIGRhdGEuZnJhbWUoKSAlPiUKIyAgIGdncGxvdChhZXMoeCA9IGNvbmR2YWwpKSArCiMgICBmYWNldF9ncmlkKH50ZXJtLCBzY2FsZXMgPSAiZnJlZSIpICsKIyAgIGdlb21faGlzdG9ncmFtKCkgKwojICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbHR5ID0gMiwgY29sb3IgPSAiYmx1ZSIpCmBgYAoKCiMgSW5kaXZpZHVhbCByZWdyZXNzaW9ucwoKYGBge3J9CnN1YmlkcyA8LSBsZXZlbHMoZmFjdG9yKGRfY2F0X3Njb3JlZCRzdWJpZCkpICU+JSBhcy5udW1lcmljKCkKYGBgCgpgYGB7cn0KIyByZW1pbmRlciBvZiBjb250cmFzdHMKY29udHJhc3RzKGRfY2F0X3Njb3JlZCRmYWN0b3IpCmBgYAoKCmBgYHtyfQpyZWdfZnVuIDwtIGZ1bmN0aW9uKHRoaXNfc3ViaWQpewogIHIgPC0gbG0oc2NvcmUgfiBmYWN0b3IgKiBwb2x5KHRhcmdldF9udW0sIDMpLAogICAgICAgICAgZF9jYXRfc2NvcmVkICU+JSBmaWx0ZXIoc3ViaWQgPT0gdGhpc19zdWJpZCkpCiAgCiAgY29lZmZzIDwtIHN1bW1hcnkocikkY29lZmZpY2llbnRzICU+JQogICAgZGF0YS5mcmFtZSgpICU+JQogICAgcm93bmFtZXNfdG9fY29sdW1uKCJwYXJhbSIpICU+JQogICAgbXV0YXRlKHN1YmlkID0gdGhpc19zdWJpZCkKICAKICByZXR1cm4oY29lZmZzKQp9CgppbmRpdl9jb2VmZnMgPC0gZGF0YS5mcmFtZShwYXJhbSA9IGNoYXJhY3RlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBFc3RpbWF0ZSA9IG51bWVyaWMoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RkLi5FcnJvciA9IG51bWVyaWMoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdC52YWx1ZSA9IG51bWVyaWMoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgUHIuLi50Li4gPSBudW1lcmljKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YmlkID0gbnVtZXJpYygpKQpmb3IoaSBpbiAxOmxlbmd0aChzdWJpZHMpKXsKICBjdXJyZW50X2NvZWZmcyA8LSByZWdfZnVuKHN1Ymlkc1tpXSkKICBpbmRpdl9jb2VmZnMgPC0gaW5kaXZfY29lZmZzICU+JQogICAgZnVsbF9qb2luKGN1cnJlbnRfY29lZmZzKQp9CgppbmRpdl9jb2VmZnMgPC0gaW5kaXZfY29lZmZzICU+JQogIHJlbmFtZShiID0gRXN0aW1hdGUsCiAgICAgICAgIGJfc2UgPSBTdGQuLkVycm9yLAogICAgICAgICB0ID0gdC52YWx1ZSwKICAgICAgICAgdF9wID0gUHIuLi50Li4pCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDUsIGZpZy5hc3AgPSAxfQppbmRpdl9jb2VmZnMgJT4lCiAgbXV0YXRlKHNpZ25pZiA9IGNhc2Vfd2hlbih0X3AgPCAwLjAwMDAxIH4gInAgPCAwLjAwMDAxIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X3AgPCAwLjAwMDEgfiAicCA8IDAuMDAwMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X3AgPCAwLjAwMSB+ICJwIDwgMC4wMDEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9wIDwgMC4wMSB+ICJwIDwgMC4wMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X3AgPCAwLjA1IH4gInAgPCAwLjA1IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfcCA+PSAwLjA1IH4gIm4ucy4iKSwKICAgICAgICAgc2lnbmlmID0gZmFjdG9yKHNpZ25pZiwKICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIm4ucy4iLCAicCA8IDAuMDUiLCAicCA8IDAuMDEiLCAicCA8IDAuMDAxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInAgPCAwLjAwMDEiLCAicCA8IDAuMDAwMDEiKSksCiAgICAgICAgIHBhcmFtID0gcmVjb2RlX2ZhY3RvcihwYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoSW50ZXJjZXB0KSIgPSAib3ZlcmFsbCBhdCBiaXJ0aCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG9seSh0YXJnZXRfbnVtLCAzKTEiID0gIm92ZXJhbGwgbGluZWFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb2x5KHRhcmdldF9udW0sIDMpMiIgPSAib3ZlcmFsbCBxdWFkcmF0aWMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBvbHkodGFyZ2V0X251bSwgMykzIiA9ICJvdmVyYWxsIGN1YmljIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWN0b3Jib2RfZ20iID0gImJvZGlseSBhdCBiaXJ0aCB2cy4gR00iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZhY3RvcmJvZF9nbTpwb2x5KHRhcmdldF9udW0sIDMpMSIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJvZGlseSBsaW5lYXIgdnMuIEdNIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWN0b3Jib2RfZ206cG9seSh0YXJnZXRfbnVtLCAzKTIiID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJib2RpbHkgcXVhZHJhdGljIHZzLiBHTSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFjdG9yYm9kX2dtOnBvbHkodGFyZ2V0X251bSwgMykzIiA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYm9kaWx5IGN1YmljIHZzLiBHTSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFjdG9yY29nX2dtIiA9ICJjb2duaXRpdmUgYXQgYmlydGggdnMuIEdNIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWN0b3Jjb2dfZ206cG9seSh0YXJnZXRfbnVtLCAzKTEiID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb2duaXRpdmUgbGluZWFyIHZzLiBHTSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFjdG9yY29nX2dtOnBvbHkodGFyZ2V0X251bSwgMykyIiA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29nbml0aXZlIHF1YWRyYXRpYyB2cy4gR00iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZhY3RvcmNvZ19nbTpwb2x5KHRhcmdldF9udW0sIDMpMyIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvZ25pdGl2ZSBjdWJpYyB2cy4gR00iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZhY3RvcnBvc19nbSIgPSAicG9zaXRpdmUgYXQgYmlydGggdnMuIEdNIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWN0b3Jwb3NfZ206cG9seSh0YXJnZXRfbnVtLCAzKTEiID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb3NpdGl2ZSBsaW5lYXIgdnMuIEdNIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWN0b3Jwb3NfZ206cG9seSh0YXJnZXRfbnVtLCAzKTIiID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb3NpdGl2ZSBxdWFkcmF0aWMgdnMuIEdNIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWN0b3Jwb3NfZ206cG9seSh0YXJnZXRfbnVtLCAzKTMiID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb3NpdGl2ZSBjdWJpYyB2cy4gR00iKSwKICAgICAgICAgZmFjdG9yID0gY2FzZV93aGVuKGdyZXBsKCJvdmVyYWxsIiwgcGFyYW0pIH4gIm92ZXJhbGwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBncmVwbCgibmVnIiwgcGFyYW0pIH4gIm5lZ2F0aXZlIGVtb3Rpb25zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJib2QiLCBwYXJhbSkgfiAiYm9kaWx5IHNlbnNhdGlvbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoImNvZyIsIHBhcmFtKSB+ICJjb2duaXRpb24gJiBjb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJwb3MiLCBwYXJhbSkgfiAicG9zaXRpdmUvc29jaWFsIGVtb3Rpb25zIiksCiAgICAgICAgIGZhY3RvciA9IGZhY3RvcihmYWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJvdmVyYWxsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyJuZWdhdGl2ZSBlbW90aW9ucyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29nbml0aW9uICYgY29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJib2RpbHkgc2Vuc2F0aW9ucyIsICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBvc2l0aXZlL3NvY2lhbCBlbW90aW9ucyIpKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gYiwgZmlsbCA9IGZhY3RvciwgYWxwaGEgPSBzaWduaWYpKSArCiAgZmFjZXRfd3JhcCh+IHBhcmFtLCBzY2FsZXMgPSAiZnJlZSIpICsKICBnZW9tX2hpc3RvZ3JhbShmaWxsID0gImJsYWNrIiwgYWxwaGEgPSAxKSArCiAgZ2VvbV9oaXN0b2dyYW0oKSArCiAgIyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiLCBuYS52YWx1ZSA9ICJncmF5IikKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjYTZkODU0IiwgIiNmYzhkNjIiLCAiIzhkYTBjYiIsICIjZTc4YWMzIikpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDUsIGZpZy5hc3AgPSAxLCBpbmNsdWRlID0gRn0KaW5kaXZfY29lZmZzICU+JQogIG11dGF0ZShzaWduaWYgPSBjYXNlX3doZW4odF9wIDwgMC4wMDAwMSB+ICJwIDwgMC4wMDAwMSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9wIDwgMC4wMDAxIH4gInAgPCAwLjAwMDEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9wIDwgMC4wMDEgfiAicCA8IDAuMDAxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfcCA8IDAuMDEgfiAicCA8IDAuMDEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9wIDwgMC4wNSB+ICJwIDwgMC4wNSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X3AgPj0gMC4wNSB+ICJuLnMuIiksCiAgICAgICAgIHNpZ25pZiA9IGZhY3RvcihzaWduaWYsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJuLnMuIiwgInAgPCAwLjA1IiwgInAgPCAwLjAxIiwgInAgPCAwLjAwMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwIDwgMC4wMDAxIiwgInAgPCAwLjAwMDAxIikpLAogICAgICAgICBwYXJhbSA9IHJlY29kZV9mYWN0b3IocGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKEludGVyY2VwdCkiID0gIm92ZXJhbGwgYXQgYmlydGgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBvbHkodGFyZ2V0X251bSwgMykxIiA9ICJvdmVyYWxsIGxpbmVhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG9seSh0YXJnZXRfbnVtLCAzKTIiID0gIm92ZXJhbGwgcXVhZHJhdGljIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb2x5KHRhcmdldF9udW0sIDMpMyIgPSAib3ZlcmFsbCBjdWJpYyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFjdG9yYm9kX2dtIiA9ICJib2RpbHkgYXQgYmlydGggdnMuIEdNIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWN0b3Jib2RfZ206cG9seSh0YXJnZXRfbnVtLCAzKTEiID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJib2RpbHkgbGluZWFyIHZzLiBHTSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFjdG9yYm9kX2dtOnBvbHkodGFyZ2V0X251bSwgMykyIiA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYm9kaWx5IHF1YWRyYXRpYyB2cy4gR00iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZhY3RvcmJvZF9nbTpwb2x5KHRhcmdldF9udW0sIDMpMyIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJvZGlseSBjdWJpYyB2cy4gR00iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZhY3RvcmNvZ19nbSIgPSAiY29nbml0aXZlIGF0IGJpcnRoIHZzLiBHTSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFjdG9yY29nX2dtOnBvbHkodGFyZ2V0X251bSwgMykxIiA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29nbml0aXZlIGxpbmVhciB2cy4gR00iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZhY3RvcmNvZ19nbTpwb2x5KHRhcmdldF9udW0sIDMpMiIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvZ25pdGl2ZSBxdWFkcmF0aWMgdnMuIEdNIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWN0b3Jjb2dfZ206cG9seSh0YXJnZXRfbnVtLCAzKTMiID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb2duaXRpdmUgY3ViaWMgdnMuIEdNIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWN0b3Jwb3NfZ20iID0gInBvc2l0aXZlIGF0IGJpcnRoIHZzLiBHTSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFjdG9ycG9zX2dtOnBvbHkodGFyZ2V0X251bSwgMykxIiA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG9zaXRpdmUgbGluZWFyIHZzLiBHTSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFjdG9ycG9zX2dtOnBvbHkodGFyZ2V0X251bSwgMykyIiA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG9zaXRpdmUgcXVhZHJhdGljIHZzLiBHTSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFjdG9ycG9zX2dtOnBvbHkodGFyZ2V0X251bSwgMykzIiA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG9zaXRpdmUgY3ViaWMgdnMuIEdNIikpICU+JQogIGdncGxvdChhZXMoeCA9IGIsIGZpbGwgPSBzaWduaWYpKSArCiAgZmFjZXRfd3JhcCh+IHBhcmFtLCBzY2FsZXMgPSAiZnJlZSIpICsKICBnZW9tX2hpc3RvZ3JhbShmaWxsID0gImJsYWNrIiwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9oaXN0b2dyYW0oKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJCbHVlcyIsIG5hLnZhbHVlID0gImdyYXkiKQogICMgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiZ3JheSIsICJ0dXJxdW9pc2UiKSkKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNSwgZmlnLmFzcCA9IDIsIGluY2x1ZGUgPSBGfQpkX2NhdF9zY29yZWQgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IGZhY3Rvcl9uYW1lcykpICsKICBmYWNldF93cmFwKH4gc3ViaWQpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikKYGBgCgpgYGB7cn0KaW5kaXZfY29lZmZzICU+JQogIHNlbGVjdChzdWJpZCwgcGFyYW0sIGIpICU+JQogIHNwcmVhZChwYXJhbSwgYikgJT4lCiAgYXJyYW5nZShkZXNjKGBmYWN0b3Jib2RfZ206cG9seSh0YXJnZXRfbnVtLCAzKTFgKSwKICAgICAgICAgIGRlc2MoYGZhY3RvcmJvZF9nbTpwb2x5KHRhcmdldF9udW0sIDMpMmApLAogICAgICAgICAgZGVzYyhgZmFjdG9yYm9kX2dtOnBvbHkodGFyZ2V0X251bSwgMykzYCkpICU+JQogIG11dGF0ZShvcmRlciA9IDE6bGVuZ3RoKHN1YmlkcykpICU+JQogIGRpc3RpbmN0KHN1YmlkLCBvcmRlcikKYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9IDYsIGZpZy5hc3AgPSAxLjV9CmRfY2F0X3Njb3JlZCAlPiUKICBmaWx0ZXIoZmFjdG9yID09ICJNUjMiKSAlPiUgIyBNUjMgPSBib2RpbHkgc2Vuc2F0aW9ucwogIGZ1bGxfam9pbihkX2NhdF9zY29yZWQgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKHRhcmdldF9udW0gPT0gMCwgZmFjdG9yID09ICJNUjMiKSAlPiUKICAgICAgICAgICAgICBkaXN0aW5jdChzdWJpZCwgc2NvcmUpICU+JQogICAgICAgICAgICAgIGFycmFuZ2Uoc2NvcmUpICU+JQogICAgICAgICAgICAgIG11dGF0ZShvcmRlciA9IDE6bGVuZ3RoKHN1YmlkcyksCiAgICAgICAgICAgICAgICAgICAgIHN1YmlkID0gYXMuY2hhcmFjdGVyKHN1YmlkKSkgJT4lCiAgICAgICAgICAgICAgZGlzdGluY3Qoc3ViaWQsIG9yZGVyKSkgJT4lCiAgIyBmdWxsX2pvaW4oaW5kaXZfY29lZmZzICU+JQogICMgICAgICAgICAgICAgc2VsZWN0KHN1YmlkLCBwYXJhbSwgYikgJT4lCiAgIyAgICAgICAgICAgICBzcHJlYWQocGFyYW0sIGIpICU+JQogICMgICAgICAgICAgICAgYXJyYW5nZShgZmFjdG9yYm9kX2dtYCkgJT4lCiAgIyAgICAgICAgICAgICAjIGFycmFuZ2UoZGVzYyhgZmFjdG9yYm9kX2dtOnBvbHkodGFyZ2V0X251bSwgMykxYCkpICU+JQogICMgICAgICAgICAgICAgbXV0YXRlKG9yZGVyID0gMTpsZW5ndGgoc3ViaWRzKSwKICAjICAgICAgICAgICAgICAgICAgICBzdWJpZCA9IGFzLmNoYXJhY3RlcihzdWJpZCkpICU+JQogICMgICAgICAgICAgICAgZGlzdGluY3Qoc3ViaWQsIG9yZGVyKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlKSkgKyAKICBmYWNldF93cmFwKH4gcmVvcmRlcihzdWJpZCwgb3JkZXIpKSArCiAgZ2VvbV9saW5lKGNvbG9yID0gIiM4ZGEwY2IiLCBzaXplID0gMSkgKwogIGxhYnModGl0bGUgPSAiQm9kaWx5IHNlbnNhdGlvbnMiLAogICAgICAgIyBzdWJ0aXRsZSA9ICJPcmRlcmVkIGJ5IGNvZWZmaWNpZW50IG9mIGJvZGlseSBzZW5zYXRpb25zICh2cy4gR00pIikKICAgICAgIHN1YnRpdGxlID0gIk9yZGVyZWQgYnkgcGVyY2VpdmVkIGJvZGlseSBzZW5zYXRpb25zIGF0IGJpcnRoIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNiwgZmlnLmFzcCA9IDEuNX0KZF9jYXRfc2NvcmVkICU+JQogIGZpbHRlcihmYWN0b3IgPT0gIk1SMiIpICU+JSAjIE1SMiA9IGNvZ25pdGlvbiAmIGNvbnRyb2wKICBmdWxsX2pvaW4oZF9jYXRfc2NvcmVkICU+JQogICAgICAgICAgICAgIGZpbHRlcih0YXJnZXRfbnVtID09IDAsIGZhY3RvciA9PSAiTVIyIikgJT4lCiAgICAgICAgICAgICAgZGlzdGluY3Qoc3ViaWQsIHNjb3JlKSAlPiUKICAgICAgICAgICAgICBhcnJhbmdlKHNjb3JlKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUob3JkZXIgPSAxOmxlbmd0aChzdWJpZHMpLAogICAgICAgICAgICAgICAgICAgICBzdWJpZCA9IGFzLmNoYXJhY3RlcihzdWJpZCkpICU+JQogICAgICAgICAgICAgIGRpc3RpbmN0KHN1YmlkLCBvcmRlcikpICU+JQogICMgZnVsbF9qb2luKGluZGl2X2NvZWZmcyAlPiUKICAjICAgICAgICAgICAgIHNlbGVjdChzdWJpZCwgcGFyYW0sIGIpICU+JQogICMgICAgICAgICAgICAgc3ByZWFkKHBhcmFtLCBiKSAlPiUKICAjICAgICAgICAgICAgIGFycmFuZ2UoYGZhY3RvcmNvZ19nbWApICU+JQogICMgICAgICAgICAgICAgIyBhcnJhbmdlKGRlc2MoYGZhY3RvcmNvZ19nbTpwb2x5KHRhcmdldF9udW0sIDMpMWApKSAlPiUKICAjICAgICAgICAgICAgIG11dGF0ZShvcmRlciA9IDE6bGVuZ3RoKHN1YmlkcyksCiAgIyAgICAgICAgICAgICAgICAgICAgc3ViaWQgPSBhcy5jaGFyYWN0ZXIoc3ViaWQpKSAlPiUKICAjICAgICAgICAgICAgIGRpc3RpbmN0KHN1YmlkLCBvcmRlcikpICU+JQogIGdncGxvdChhZXMoeCA9IHRhcmdldF9udW0sIHkgPSBzY29yZSkpICsgCiAgZmFjZXRfd3JhcCh+IHJlb3JkZXIoc3ViaWQsIG9yZGVyKSkgKwogIGdlb21fbGluZShjb2xvciA9ICIjZmM4ZDYyIiwgc2l6ZSA9IDEpICsKICBsYWJzKHRpdGxlID0gIkNvZ25pdGlvbiAmIGNvbnRyb2wiLAogICAgICAgIyBzdWJ0aXRsZSA9ICJPcmRlcmVkIGJ5IGNvZWZmaWNpZW50IG9mIGNvZ25pdGlvbiAmIGNvbnRyb2wgKHZzLiBHTSkiKQogICAgICAgc3VidGl0bGUgPSAiT3JkZXJlZCBieSBwZXJjZWl2ZWQgY29nbml0aW9uICYgY29udHJvbCBhdCBiaXJ0aCIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDYsIGZpZy5hc3AgPSAxLjV9CmRfY2F0X3Njb3JlZCAlPiUKICBmaWx0ZXIoZmFjdG9yID09ICJNUjQiKSAlPiUgIyBNUjQgPSBwb3NpdGl2ZS9zb2NpYWwgZW1vdGlvbnMKICBmdWxsX2pvaW4oZF9jYXRfc2NvcmVkICU+JQogICAgICAgICAgICAgIGZpbHRlcih0YXJnZXRfbnVtID09IDAsIGZhY3RvciA9PSAiTVI0IikgJT4lCiAgICAgICAgICAgICAgZGlzdGluY3Qoc3ViaWQsIHNjb3JlKSAlPiUKICAgICAgICAgICAgICBhcnJhbmdlKHNjb3JlKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUob3JkZXIgPSAxOmxlbmd0aChzdWJpZHMpLAogICAgICAgICAgICAgICAgICAgICBzdWJpZCA9IGFzLmNoYXJhY3RlcihzdWJpZCkpICU+JQogICAgICAgICAgICAgIGRpc3RpbmN0KHN1YmlkLCBvcmRlcikpICU+JQogICMgZnVsbF9qb2luKGluZGl2X2NvZWZmcyAlPiUKICAjICAgICAgICAgICAgIHNlbGVjdChzdWJpZCwgcGFyYW0sIGIpICU+JQogICMgICAgICAgICAgICAgc3ByZWFkKHBhcmFtLCBiKSAlPiUKICAjICAgICAgICAgICAgIGFycmFuZ2UoYGZhY3RvcnBvc19nbWApICU+JQogICMgICAgICAgICAgICAgIyBhcnJhbmdlKGRlc2MoYGZhY3RvcnBvc19nbTpwb2x5KHRhcmdldF9udW0sIDMpMWApKSAlPiUKICAjICAgICAgICAgICAgIG11dGF0ZShvcmRlciA9IDE6bGVuZ3RoKHN1YmlkcyksCiAgIyAgICAgICAgICAgICAgICAgICAgc3ViaWQgPSBhcy5jaGFyYWN0ZXIoc3ViaWQpKSAlPiUKICAjICAgICAgICAgICAgIGRpc3RpbmN0KHN1YmlkLCBvcmRlcikpICU+JQogIGdncGxvdChhZXMoeCA9IHRhcmdldF9udW0sIHkgPSBzY29yZSkpICsgCiAgZmFjZXRfd3JhcCh+IHJlb3JkZXIoc3ViaWQsIG9yZGVyKSkgKwogIGdlb21fbGluZShjb2xvciA9ICIjZTc4YWMzIiwgc2l6ZSA9IDEpICsKICBsYWJzKHRpdGxlID0gIlBvc2l0aXZlL3NvY2lhbCBlbW90aW9ucyIsCiAgICAgICAjIHN1YnRpdGxlID0gIk9yZGVyZWQgYnkgY29lZmZpY2llbnQgb2YgcG9zaXRpdmUvc29jaWFsIGVtb3Rpb25zICh2cy4gR00pIikKICAgICAgIHN1YnRpdGxlID0gIk9yZGVyZWQgYnkgcGVyY2VpdmVkIHBvc2l0aXZlL3NvY2lhbCBlbW90aW9ucyBhdCBiaXJ0aCIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDYsIGZpZy5hc3AgPSAxLjV9CmRfY2F0X3Njb3JlZCAlPiUKICBmaWx0ZXIoZmFjdG9yID09ICJNUjEiKSAlPiUgIyBNUjEgPSBuZWdhdGl2ZSBlbW90aW9ucwogIGZ1bGxfam9pbihkX2NhdF9zY29yZWQgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKHRhcmdldF9udW0gPT0gMCwgZmFjdG9yID09ICJNUjEiKSAlPiUKICAgICAgICAgICAgICBkaXN0aW5jdChzdWJpZCwgc2NvcmUpICU+JQogICAgICAgICAgICAgIGFycmFuZ2Uoc2NvcmUpICU+JQogICAgICAgICAgICAgIG11dGF0ZShvcmRlciA9IDE6bGVuZ3RoKHN1YmlkcyksCiAgICAgICAgICAgICAgICAgICAgIHN1YmlkID0gYXMuY2hhcmFjdGVyKHN1YmlkKSkgJT4lCiAgICAgICAgICAgICAgZGlzdGluY3Qoc3ViaWQsIG9yZGVyKSkgJT4lCiAgIyBmdWxsX2pvaW4oaW5kaXZfY29lZmZzICU+JQogICMgICAgICAgICAgICAgc2VsZWN0KHN1YmlkLCBwYXJhbSwgYikgJT4lCiAgIyAgICAgICAgICAgICBzcHJlYWQocGFyYW0sIGIpICU+JQogICMgICAgICAgICAgICAgYXJyYW5nZShgZmFjdG9ybmVnX2dtYCkgJT4lCiAgIyAgICAgICAgICAgICAjIGFycmFuZ2UoZGVzYyhgZmFjdG9ybmVnX2dtOnBvbHkodGFyZ2V0X251bSwgMykxYCkpICU+JQogICMgICAgICAgICAgICAgbXV0YXRlKG9yZGVyID0gMTpsZW5ndGgoc3ViaWRzKSwKICAjICAgICAgICAgICAgICAgICAgICBzdWJpZCA9IGFzLmNoYXJhY3RlcihzdWJpZCkpICU+JQogICMgICAgICAgICAgICAgZGlzdGluY3Qoc3ViaWQsIG9yZGVyKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlKSkgKyAKICBmYWNldF93cmFwKH4gcmVvcmRlcihzdWJpZCwgb3JkZXIpKSArCiAgZ2VvbV9saW5lKGNvbG9yID0gIiM2NmMyYTUiLCBzaXplID0gMSkgKwogIGxhYnModGl0bGUgPSAiTmVnYXRpdmUgZW1vdGlvbnMiLAogICAgICAgIyBzdWJ0aXRsZSA9ICJPcmRlcmVkIGJ5IGNvZWZmaWNpZW50IG9mIG5lZ2F0aXZlIGVtb3Rpb25zICh2cy4gR00pIikKICAgICAgIHN1YnRpdGxlID0gIk9yZGVyZWQgYnkgcGVyY2VpdmVkIG5lZ2F0aXZlIGVtb3Rpb25zIGF0IGJpcnRoIikKYGBgCg==